package com.mobile.dao.grid.base.spring;

import java.util.List;
import java.util.Map;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.mobile.dao.IBaseSpringDAO;
import com.mobile.gridUtil.GridFilter;
import com.mobile.struts.action.tools.AssociateTableInfo;
import com.mobile.tools.BeanUtil;
/**
 * 扩展HibernateTemplate类
 * @author hf
 *
 */
public class BaseSpringDAOImpl extends HibernateTemplate implements IBaseSpringDAO{
	public List getObjectsByIds(Object o,int start,int pageSize){
		Example example=Example.create(o)
								.enableLike()
								.ignoreCase();
		DetachedCriteria criteria = DetachedCriteria
									.forClass(o.getClass())
									.add(example)
									.addOrder(Order.asc("uniqueCode"));
		return this.findByCriteria(criteria, start, pageSize);
	}
	
	public List findByExample(Object o,String[] orders){
		Example example=Example.create(o);
		DetachedCriteria criteria = DetachedCriteria
									.forClass(o.getClass())
									.add(example);
		for(String order:orders){
			criteria.addOrder(Order.asc(order));
		}									
		return this.findByCriteria(criteria);
	}
	
	public List findByExample(Object o,List<Order> orders){
		Example example=Example.create(o);
		DetachedCriteria criteria = DetachedCriteria
									.forClass(o.getClass())
									.add(example);
		for(Order order:orders){
			criteria.addOrder(order);
		}									
		return this.findByCriteria(criteria);
	}
	/**
	 * 有表关联的查询
	 * @param sourceObject				要查找的类的实例
	 * @param associatedName			关联类在类中的属性名字数组
	 * @param associatedObject			关联类的实例
	 * @return
	 */
	public List findByAssociatedObjectsExample(Object sourceObject,String[] associatedName,Object[] associatedObject){
		List list=null;
		Example sourceExample=Example.create(sourceObject);
		DetachedCriteria criteria = DetachedCriteria
									.forClass(sourceObject.getClass())
									.add(sourceExample);
		for(int i=0;i<associatedName.length;i++){
			criteria.createCriteria(associatedName[i])
					.add(Example.create(associatedObject[i]));
			
		}
		list=this.findByCriteria(criteria);
		return list;
	}
	/**
	 * 自关联查询
	 * @param sourceObject		源对象	
	 * @param associatedName	关联对对象名
	 * @param associatedObject	关联对象
	 * @param orders			排序对象
	 * @return
	 */
	public List findByMyselfAssociatedExample(
			Object sourceObject,
			String[] associatedName,
			Object[] associatedObjects,
			String[] orders){
		List list=null;
		Example sourceExample=Example.create(sourceObject);
		DetachedCriteria criteria = DetachedCriteria
									.forClass(sourceObject.getClass())
									.add(sourceExample);
		for(int i=0;i<associatedName.length;i++){
			criteria.createAlias(associatedName[i],associatedName[i]+i);
			Object associatedObject=associatedObjects[i];
			Map<String,Object> map=BeanUtil.javaBeanToMap(associatedObject);
			for(Map.Entry<String, Object> entry:map.entrySet()){
				criteria.add(Restrictions.eq(associatedName[i]+i+"."+entry.getKey(),entry.getValue()));
			}
		}
		
		for(String order:orders){
			criteria.addOrder(Order.asc(order));
		}	
		list=this.findByCriteria(criteria);
		return list;
	}
	
	public void deleteById(Object o,String uniqueCode){
		this.delete(findById(o,uniqueCode));
	}
	public void deleteById(Class clazz,String uniqueCode){
		this.delete(findById(clazz,uniqueCode));
	}
	public void deleteById(String entityName,String uniqueCode){
		this.delete(findById(entityName,uniqueCode));
	}
	public void deleteById(Object o,String[] uniqueCodes){
		for(String uniqueCode:uniqueCodes){
			deleteById(o,uniqueCode);
		}
	}
	public void deleteById(Class clazz,String[] uniqueCodes){
		for(String uniqueCode:uniqueCodes){
			deleteById(clazz,uniqueCode);
		}
	}
	public void deleteById(String entityName,String[] uniqueCodes){
		for(String uniqueCode:uniqueCodes){
			deleteById(entityName,uniqueCode);
		}	
	}
	public Object findById(Object o,String id){
		return this.get(o.getClass(), id);
	}
	public Object findById(Class clazz,String id){
		return this.get(clazz, id);
	}
	public Object findById(String entityName,String id){
		return this.get(entityName, id);
	}

	public List findList(Object o,int start,int pageSize){
		Example example=Example.create(o)
				.enableLike()
				.ignoreCase();
		DetachedCriteria criteria = DetachedCriteria
					.forClass(o.getClass())
					.add(example)
					.addOrder(Order.asc("uniqueCode"));
		return this.findByCriteria(criteria, start, pageSize);
	}
	public List findList(Object o,String entityName,int start,int pageSize){
		Example example=Example.create(o)
				.enableLike()
				.ignoreCase();
		DetachedCriteria criteria = DetachedCriteria
					.forEntityName(entityName)
					.add(example)
					.addOrder(Order.asc("uniqueCode"));
		return this.findByCriteria(criteria, start, pageSize);
	}
	
	/**
	 * 获得总数
	 * @param cl				域模型的类
	 * @param gridFilterList	要过滤的列表值
	 * @return 返回整型值
	 */
	public int getTotalSize(Class cl,List<GridFilter> gridFilterList){
		/**
		 * 查询总数，设置总条数
		 */
		DetachedCriteria criteria=createDetachedCriteria(cl,gridFilterList)
							.setProjection(Projections.count("uniqueCode"));
		
		return (Integer)this.findByCriteria(criteria).get(0);
	}
	/**
	 * 获得总数
	 * @param pojo				域模型的类
	 * @param gridFilterList	要过滤的列表值
	 * @return 返回整型值
	 */
	public int getTotalSize(Object pojo,List<GridFilter> gridFilterList){
		/**
		 * 查询总数，设置总条数
		 */
		Example example=Example.create(pojo);
		DetachedCriteria criteria=createDetachedCriteria(pojo.getClass(),gridFilterList)
							.add(example)
							.setProjection(Projections.count("uniqueCode"));
		
		return (Integer)this.findByCriteria(criteria).get(0);
	}
	/**
	 * 获得总数
	 * @param pojo				域模型的类
	 * @param gridFilterList	要过滤的列表值
	 * @return 返回整型值
	 */
	public int getTotalSize(Object pojo,List<GridFilter> gridFilterList,List<AssociateTableInfo> associateList){
		/**
		 * 查询总数，设置总条数
		 */
		Example example=Example.create(pojo);
		DetachedCriteria criteria=createDetachedCriteria(pojo.getClass(),gridFilterList)
							.add(example)
							.setProjection(Projections.count("uniqueCode"));
		for(AssociateTableInfo ati :  associateList ){
			DetachedCriteria criteria2=criteria.createCriteria(ati.getAssociatedName());
			Object obj = ati.getBean();
			if(obj!=null){
				criteria2.add(Example.create(obj));
			}
			Map<String,Object> map = ati.getMap();
			if(!map.isEmpty()){
				for(Map.Entry<String, Object> entry:map.entrySet()){
					criteria2.add(Restrictions.eq(entry.getKey(),entry.getValue())) ;
				}		
			}
			
		}
		
		return (Integer)this.findByCriteria(criteria).get(0);
	}
	/**
	 * 获得分页数据
	 * @param start				开始读取的索引
	 * @param pageSize			总共读取的数目
	 * @param cl				域模型的类
	 * @param gridFilterList	要过滤的列表值
	 * @return					列表
	 */
	public List getPageList(int start,int pageSize,Class cl,List<GridFilter> gridFilterList){
		DetachedCriteria criteria = createDetachedCriteria(cl,gridFilterList)
									.addOrder(Order.asc("uniqueCode"));
		
		List list=this.findByCriteria(criteria,start,pageSize);
		return list;
	}
	/**
	 * 获得分页数据
	 * @param start				开始读取的索引
	 * @param pageSize			总共读取的数目
	 * @param pojo				域模型的类
	 * @param gridFilterList	要过滤的列表值
	 * @return					列表
	 */
	public List getPageList(int start,int pageSize,Object pojo,List<GridFilter> gridFilterList){
		Example example=Example.create(pojo);
		DetachedCriteria criteria = createDetachedCriteria(pojo.getClass(),gridFilterList)
									.addOrder(Order.asc("uniqueCode"))
									.add(example);
		List list=this.findByCriteria(criteria,start,pageSize);
		return list;
	}
	/**
	 * 
	 * @param start				开始读取的索引
	 * @param pageSize			总共读取的数目
	 * @param pojo				域模型的类
	 * @param gridFilterList	要过滤的列表值
	 * @return					列表
	 */
	public List getPageList(int start,int pageSize,Object pojo,List<GridFilter> gridFilterList,List<AssociateTableInfo> associateList){
		Example example=Example.create(pojo);
		DetachedCriteria criteria = createDetachedCriteria(pojo.getClass(),gridFilterList)
									.addOrder(Order.asc("uniqueCode"))
									.add(example);
		for(AssociateTableInfo ati :  associateList ){
			DetachedCriteria criteria2=criteria.createCriteria(ati.getAssociatedName());
			Object obj = ati.getBean();
			if(obj!=null){
				criteria2.add(Example.create(obj));
			}
			Map map = ati.getMap();
			if(!map.isEmpty()){
				criteria2.add(Restrictions.allEq(map)) ;
			}
			
		}
		List list=this.findByCriteria(criteria,start,pageSize);
		return list;
	}
	/**
	 * 
	 * @param cl				要处理的类的类
	 * @param gridFilterList	
	 * @return
	 */
	protected DetachedCriteria createDetachedCriteria(Class cl,List<GridFilter> gridFilterList){
		DetachedCriteria criteria=DetachedCriteria.forClass(cl);
		for(GridFilter gf :gridFilterList){
			gf.createCriteria(criteria);
		}
		return criteria;
	}
	/**
	 * 获得所有数据
	 * @param cl				域模型的类
	 * @param gridFilterList	要过滤的列表值
	 * @return					列表
	 */
	public List getAllList(Class cl,List<GridFilter> gridFilterList){
		DetachedCriteria criteria = createDetachedCriteria(cl,gridFilterList)
									.addOrder(Order.asc("uniqueCode"));
		List list=this.findByCriteria(criteria);
		return list;
	}
	/**
	 * 获得所有数据
	 * @param pojo				域模型的类
	 * @param gridFilterList	要过滤的列表值
	 * @return					列表
	 */
	public List getAllList(Object pojo,List<GridFilter> gridFilterList){
		Example example=Example.create(pojo);
		DetachedCriteria criteria = createDetachedCriteria(pojo.getClass(),gridFilterList)
									.addOrder(Order.asc("uniqueCode"))
									.add(example);
		List list=this.findByCriteria(criteria);
		return list;
	}
	/**
	 * 获得符合pojo条件的数据
	 * @param pojo				域模型的类
	 * @return					列表
	 */
	public List getAllList(Object pojo){
		Example example=Example.create(pojo);
		DetachedCriteria criteria=DetachedCriteria.forClass(pojo.getClass())
									.addOrder(Order.asc("uniqueCode"))
									.add(example);
		List list=this.findByCriteria(criteria);
		return list;
	}
}
